package com.fin.zw.aiqas.service;

import com.fin.zw.aiqas.entity.InspectionInfo;
import com.fin.zw.aiqas.entity.QInspectionInfo;
import com.fin.zw.aiqas.enums.InspTask;
import com.fin.zw.aiqas.enums.TaskType;
import com.fin.zw.aiqas.model.request.InspectionFileRequest;
import com.fin.zw.aiqas.model.request.InspectionInfoRequest;
import com.fin.zw.aiqas.model.session.SessionModel;
import com.fin.zw.aiqas.repository.InspectionRepository;
import com.fin.zw.aiqas.util.BadRequestException;
import com.fin.zw.aiqas.util.CSVUtils;
import com.google.common.collect.Lists;
import com.querydsl.core.BooleanBuilder;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.*;


@Service(value = "inspectionService")
public class InspectionService {

    private final static Logger log = LoggerFactory.getLogger(InspectionService.class);
    @Autowired
    private InspectionRepository inspectionRepository;
    @Value("${file.filepath}")
    private String filepath;

    /**
     * 质检信息的创建
     */
    public void addInspection(InspectionInfoRequest request, SessionModel session) {
        log.info("添加质检结果数据信息...");
        InspectionInfo info = new InspectionInfo();
        BeanUtils.copyProperties(request, info);
        info.setCreateTime(new Date());
/*        info.setOperatorId(session.getUserId());
        info.setOperatorRealName(session.getUserName());*/
        inspectionRepository.save(info);
        log.info("质检结果添加执行成功！！");
    }

    /**
     * 质检信息的修改
     *
     * @param request
     * @throws Exception
     */
    public void updateInspection(InspectionInfoRequest request, SessionModel session) throws RuntimeException {
        log.info("修改质检结果数据信息...");
        Optional<InspectionInfo> optional = inspectionRepository.findById(request.getId());
        if (!optional.isPresent()) {
            throw new BadRequestException("", "需要修改的质检信息不存在！");
        }
        InspectionInfo info = optional.get();
        BeanUtils.copyProperties(request, info);
        inspectionRepository.save(info);
        log.info("质检结果修改成功！！");
    }

    /**
     * 根据ID删除inspection_info数据
     */
    public void deleteInspection(Long id) throws Exception {
        log.info("删除ID为[" + id + "]的检结果数据信息...");
        Optional<InspectionInfo> info = inspectionRepository.findById(id);
        if (!info.isPresent()) {
            throw new BadRequestException("", "删除的质检信息不存在！");
        }
        inspectionRepository.delete(info.get());
    }

    /**
     * 条件匹配分页查询
     */
    public Page<InspectionInfo> queryRuleTable(InspectionInfoRequest request, Pageable pageable) throws Exception {
        log.info("开始查询质检结果列表信息");
        BooleanBuilder builder = new BooleanBuilder();
        QInspectionInfo qInspection = QInspectionInfo.inspectionInfo;
        if (StringUtils.isNotBlank(request.getInspectionBatch()))
            builder.and(qInspection.inspectionBatch.eq(request.getInspectionBatch()));
        if (request.getTaskId() != null)
            builder.and(qInspection.taskInfo.id.eq(request.getTaskId()));
        if (StringUtils.isNotBlank(request.getTaskName()))
            builder.and(qInspection.taskInfo.name.like("%" + request.getTaskName() + "%"));
        if (request.getStartTime() != null && request.getEndTime() != null)
            builder.and(qInspection.runDate.between(request.getStartTime(), request.getEndTime()));//任务执行时间
        if (request.getTaskStatus() != null) builder.and(qInspection.taskStatus.eq(request.getTaskStatus()));//任务状态
        Page<InspectionInfo> page = inspectionRepository.findAll(builder, pageable);
        log.info("查询质检结果列表信息已完成");
        return page;
    }


    /**
     * 导出为VCS文件
     */
    public File exportFile(InspectionFileRequest request) throws Exception {
        log.info("开始查询数据......");
        BooleanBuilder builder = new BooleanBuilder();
        QInspectionInfo qInspection = QInspectionInfo.inspectionInfo;
        if (request.getStartTime() != null && request.getEndTime() != null)
            builder.and(qInspection.runDate.between(request.getStartTime(), request.getEndTime()));//任务执行时间
        if (StringUtils.isNotBlank(request.getTaskStatus()))
            builder.and(qInspection.taskStatus.eq(InspTask.valueOf(request.getTaskStatus())));
        LinkedHashMap<String, Object> headMap = new LinkedHashMap();
        headMap.put("taskName", "任务名称");
        headMap.put("taskType", "任务类型");
        headMap.put("inspectionBatch", "任务批次");
        headMap.put("taskStatus", "任务状态");
        headMap.put("runDate", "任务执行日期");
        headMap.put("voiceNum", "采集录音数量");
        headMap.put("complateNum", "已完成质检数量");
        headMap.put("hitNum", "质检命中规则数量");
        headMap.put("hitScale", "质检命中比例");
        Iterator<InspectionInfo> iterator = inspectionRepository.findAll(builder, new Sort(Sort.Direction.DESC, "runDate")).iterator();
        List<LinkedHashMap> exportDataList = new ArrayList<LinkedHashMap>();
        while (iterator.hasNext()) {
            LinkedHashMap<String, String> rowMap = new LinkedHashMap<String, String>();
            InspectionInfo info = iterator.next();
            rowMap.put("taskName", info.getTaskInfo().getName());
            rowMap.put("taskType",
                    info.getTaskInfo().getTaskType() == null ?
                            null : ((info.getTaskInfo().getTaskType()).equals(TaskType.AUTOMATIC) ? "自动" : "手动"));
            rowMap.put("inspectionBatch", info.getInspectionBatch());
            //读取任务状态
            switch (info.getTaskStatus()) {
                case EXCUTING:
                    rowMap.put("taskStatus", "执行中");
                    break;
                case FINISH:
                    rowMap.put("taskStatus", "完成");
                    break;
                default:
                    rowMap.put("taskStatus", null);
                    break;
            }
            rowMap.put("runDate", new SimpleDateFormat("yyyy/MM/dd").format(info.getRunDate()));
            rowMap.put("voiceNum", info.getVoiceNum() != null ? info.getVoiceNum().toString() : null);
            rowMap.put("complateNum", info.getComplateNum() != null ? info.getComplateNum().toString() : null);
            rowMap.put("hitNum", info.getHitNum() != null ? info.getHitNum().toString() : null);
            rowMap.put("hitScale", info.getHitScale() != null ? info.getHitScale().toString() : null);
            exportDataList.add(rowMap);
        }
        log.info("数据获取和组装已经完成......");
        File dir = new File(filepath);
        //文件目录不存在时则创建
        if (!dir.exists() || !dir.isDirectory()) {
            dir.mkdirs();
        }
        log.info("CSV文件开始制作......");
        return CSVUtils.createCSVFile(exportDataList, headMap, filepath, request.getFileName() != null ? request.getFileName() : "Download");
    }

    public List<InspectionInfo> fetchByTaskId(Long taskId) {
        QInspectionInfo qInspectionInfo = QInspectionInfo.inspectionInfo;
        BooleanBuilder builder = new BooleanBuilder();
        builder.and(qInspectionInfo.taskInfo.id.eq(taskId));
        Iterable<InspectionInfo> inspectionInfoIterable = inspectionRepository.findAll(builder);
        ArrayList<InspectionInfo> inspectionInfos = Lists.newArrayList(inspectionInfoIterable);
        return inspectionInfos;
    }

}
